package itsm.isperp.framework.quartz.service;

import itsm.isperp.framework.quartz.domain.JobDefinition;
import itsm.isperp.framework.quartz.domain.RunJob;
import itsm.isperp.framework.quartz.provider.IRunJobProvider;
import itsm.isperp.framework.quartz.provider.ISystemJobProvider;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * 定时作业的初始器
 * 
 * <p>
 * 通过Spring的注入实现系统启动是根据依赖服务启动相关的作业服务
 * </p>
 * 
 * @author lizx
 * @since 1.0
 * 
 */
public class Initializer implements ApplicationContextAware, InitializingBean {
	public static final String BEAN_ID = "isperp.job.initializer";
	private ISchedulerService schedulerService;
	private IJobService<JobDefinition> jobService;
	private Collection<ISystemJobProvider> systemJobProviders;
	private Collection<IRunJobProvider> runJobProviders;

	protected final Log logger = LogFactory.getLog(Initializer.class);

	/**
	 * 在系统启动时初始化运行任务
	 * 
	 * @throws SchedulerException
	 */
	public void initRunJobsForStartup() throws SchedulerException {
		for (IRunJobProvider p : runJobProviders) {
			for (RunJob runJob : p.getRunJobs()) {
				if (runJob.getJobDefinition() != null) {
					if (runJob.getJobDetail() != null) {
						jobService.addJobToScheduler(runJob.getJobDefinition(),
								runJob.getJobDetail());
					} else {
						jobService.addJobToScheduler(runJob.getJobDefinition());
					}
				}
			}
		}
	}

	/**
	 * 初始化系统任务
	 * 
	 * @throws Exception
	 */
	public void initSystemJobs() throws Exception {
		Scheduler scheduler = schedulerService.retrieveScheduler();
		for (ISystemJobProvider provider : systemJobProviders) {
			scheduler.scheduleJob(provider.getJobDetail(),
					provider.getTrigger());
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		systemJobProviders = applicationContext.getBeansOfType(
				ISystemJobProvider.class).values();
		runJobProviders = applicationContext.getBeansOfType(
				IRunJobProvider.class).values();
	}

	/**
	 * 启动作业实例
	 * 
	 * @throws Exception
	 */
	public void startJobInstance() throws Exception {
		if (schedulerService.isRunJobInCurrentInstance()) {
			initRunJobsForStartup();
			initSystemJobs();
			Scheduler scheduler = schedulerService.retrieveScheduler();
			if (scheduler.isInStandbyMode()) {
				logger.info("Start scheduler [" + scheduler.getSchedulerName()
						+ "]...");
				scheduler.start();
			}
		}
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if (schedulerService.isRunJobInCurrentInstance()) {
			startJobInstance();
		}
	}

	public ISchedulerService getSchedulerService() {
		return schedulerService;
	}

	public void setSchedulerService(ISchedulerService schedulerService) {
		this.schedulerService = schedulerService;
	}

	public IJobService<JobDefinition> getJobService() {
		return jobService;
	}

	public void setJobService(IJobService<JobDefinition> jobService) {
		this.jobService = jobService;
	}
}
